package com.codeavatar.catools.tool;
/*
 * +----------------------------------------------------------------------
 * | @Author: codeavatar   @Year：2021
 * +----------------------------------------------------------------------
 * | @Email: codeavatar@aliyun.com
 * +----------------------------------------------------------------------
 */

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.drawable.Drawable;
import android.text.Html;
import android.text.Spanned;
import android.text.TextUtils;

import com.codeavatar.catools.helper.CaLogHelper;
import com.codeavatar.catools.helper.CaViewHelper;

import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
import java.util.Random;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 字符串工具类
 */
public class CaStringTool {

    private final String TAG = this.getClass().getSimpleName();

    //++++++++++++++++++++++++++++++++++++++
    //++ 外部方法
    //++++++++++++++++++++++++++++++++++++++

    /**
     * 替换目标字符串
     *
     * @param targetStr
     * @param perStrLen
     * @param splitStr
     * @return
     */
    public String insertStr(String targetStr, int perStrLen, String splitStr) {
        if (TextUtils.isEmpty(targetStr) || TextUtils.isEmpty(splitStr) || perStrLen < 1)
            return targetStr;

        int pLooper = ((targetStr.length() % perStrLen == 0) ? targetStr.length() / perStrLen :
                targetStr.length() / perStrLen + 1);
        StringBuffer sb = new StringBuffer("");
        for (int i = 0; i < pLooper; i++) {
            if (pLooper - 1 == i) {
                sb.append(targetStr.substring((i * perStrLen)));
            } else {
                sb.append(targetStr.substring((i * perStrLen), ((i + 1) * perStrLen)));
            }

            if (i + 1 < pLooper)
                sb.append(splitStr);
        }
        return sb.toString();
    }

    /**
     * 检测空
     * @param str
     * @return
     */
    public boolean isEmpty(String str) {
//        return str == null || str.trim().length() == 0;
        return TextUtils.isEmpty(str);
    }

    /**
     * 在线读取图片BitMap对象
     *
     * @param url
     * @return
     */
    public Bitmap getBitMapByUrl(String url) {
        URL myFileUrl = null;
        Bitmap bitmap = null;
        try {
            myFileUrl = new URL(url);
        } catch (MalformedURLException e) {
            e.printStackTrace();
        }
        try {
            if (myFileUrl == null)
                return null;
            HttpURLConnection conn = (HttpURLConnection) myFileUrl
                    .openConnection();
            conn.setDoInput(true);
            conn.connect();
            InputStream is = conn.getInputStream();
            bitmap = BitmapFactory.decodeStream(is);
            is.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return bitmap;
    }

    /**
     * HTML内容显示图片
     *
     * @param content
     * @return
     */
    public Spanned htmlToSpannedText(String content) {
        Spanned sp = Html.fromHtml(content, new Html.ImageGetter() {
            @Override
            public Drawable getDrawable(String source) {
                InputStream is = null;
                try {
                    is = (InputStream) new URL(source).getContent();
                    Drawable d = Drawable.createFromStream(is, "src");
                    d.setBounds(0, 0, d.getIntrinsicWidth(),
                            d.getIntrinsicHeight());
                    is.close();
                    return d;
                } catch (Exception e) {
                    return null;
                }
            }
        }, null);
        return sp;
    }

    /**
     * 插入间隔符
     *
     * @param array
     * @param separator
     * @param startIndex
     * @param endIndex
     * @return
     */
    public String join(final Object[] array, final char separator,
                              final int startIndex, final int endIndex) {
        if (array == null) {
            return null;
        }
        final int noOfItems = endIndex - startIndex;
        if (noOfItems <= 0) {
            return "";
        }
        final StringBuilder buf = new StringBuilder(noOfItems * 16);
        for (int i = startIndex; i < endIndex; i++) {
            if (i > startIndex) {
                buf.append(separator);
            }
            if (array[i] != null) {
                buf.append(array[i]);
            }
        }
        return buf.toString();
    }

    /**
     * 检测是否为汉字
     *
     * @param c
     * @return
     */
    public boolean isChinese(char c) {
        Character.UnicodeBlock ub = Character.UnicodeBlock.of(c);
        if (ub == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS
                || ub == Character.UnicodeBlock.CJK_COMPATIBILITY_IDEOGRAPHS
                || ub == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS_EXTENSION_A
                || ub == Character.UnicodeBlock.GENERAL_PUNCTUATION
                || ub == Character.UnicodeBlock.CJK_SYMBOLS_AND_PUNCTUATION
                || ub == Character.UnicodeBlock.HALFWIDTH_AND_FULLWIDTH_FORMS) {
            return true;
        }
        return false;
    }

    /**
     * 检测手机号码
     *
     * @param cellphone
     * @return
     */
    public boolean isPhone(String cellphone) {
        Pattern p = Pattern.compile("^1\\d{10}$");
        Matcher m = p.matcher(cellphone);
        return m.matches();
    }


    /**
     * 获取指定长度的随机数
     *
     * @return
     */
    public String getRndNum(int length) {
        Random random = new Random();
        StringBuilder sb = new StringBuilder("");
        while (sb.length() < length) {
            sb.append(Math.abs(random.nextLong()));
        }
        return sb.substring(0, length);
    }

    /**
     * 获取指定长度的随机字符串
     *
     * @param length
     * @return
     */
    public String getRndStr(int length) {
        String str = "8zxcv5bnml2kjhgfd4sa0qwert7yuiopQWER6TYUIO3PASDF9GHJKLZXCVBNM1";
        //由Random生成随机数
        Random random = new Random();
        StringBuffer sb = new StringBuffer("");
        //长度为几就循环几次
        for (int i = 0; i < length; ++i) {
            //产生0-61的数字
            int number = random.nextInt(62);
            //将产生的数字通过length次承载到sb中
            sb.append(str.charAt(number));
        }
        //将承载的字符转换成字符串
        return (32 == length) ? getMD5Ciphertext(sb.toString()) : sb.toString();
    }


    /**
     * 获取Md5加密后的文本
     *
     * @param plaintext
     * @return
     */
    public String getMD5Ciphertext(String plaintext) {
        MessageDigest messageDigest = null;

        try {
            messageDigest = MessageDigest.getInstance("MD5");
            messageDigest.reset();
            messageDigest.update(plaintext.getBytes("UTF-8"));
        } catch (NoSuchAlgorithmException e) {
            CaLogHelper.error(TAG, e);
        } catch (UnsupportedEncodingException e) {
            CaLogHelper.error(TAG, e);
        }

        byte[] byteArray = messageDigest.digest();
        StringBuffer md5StrBuff = new StringBuffer();
        for (int i = 0; i < byteArray.length; i++) {
            if (Integer.toHexString(0xFF & byteArray[i]).length() == 1)
                md5StrBuff.append("0").append(
                        Integer.toHexString(0xFF & byteArray[i]));
            else
                md5StrBuff.append(Integer.toHexString(0xFF & byteArray[i]));
        }
        return md5StrBuff.toString();
    }

    /**
     * 支付宝获取唯一订单编号
     *
     * @return
     */
    public String getOutTradeNo() {
        SimpleDateFormat format = new SimpleDateFormat("MMddHHmmss", Locale.getDefault());
        Date date = new Date();
        String key = format.format(date);

        Random r = new Random();
        key = key + r.nextInt();
        key = key.substring(0, 15);
        return key;
    }

    /**
     * Clear number string last zero.
     *
     * @param number
     * @return
     */
    public String getClearLastZeroNumber(String number) {
        if (TextUtils.isEmpty(number)) {
            return "";
        }

        if (number.indexOf(".") > 0) {
            number = number.replaceAll("0+?$", "");
            number = number.replaceAll("[.]$", "");
        }
        return number;
    }

    /**
     * Return whether the string is null or 0-length.
     *
     * @param str The string.
     * @return {@code true}: yes<br> {@code false}: no
     */
    public boolean isEmpty(final CharSequence str) {
        return TextUtils.isEmpty(str);
    }

    /**
     * Return whether string1 is equals to string2, ignoring case considerations..
     *
     * @param s1 The first string.
     * @param s2 The second string.
     * @return
     */
    public boolean equalsIgnoreCase(final String s1, final String s2) {
        return s1.equalsIgnoreCase(s2);
    }

    /**
     * 检测数字
     *
     * @param str
     * @return
     */
    public boolean isNumeric(CharSequence str) {
        return TextUtils.isDigitsOnly(str);
    }

    /**
     * Set the first letter of string upper.
     *
     * @param s The string.
     * @return the string with first letter upper.
     */
    public String upperFirstLetter(final String s) {
        if (s == null || s.length() == 0) return "";
        if (!Character.isLowerCase(s.charAt(0))) return s;
        return String.valueOf((char) (s.charAt(0) - 32)) + s.substring(1);
    }

    /**
     * Set the first letter of string lower.
     *
     * @param s The string.
     * @return the string with first letter lower.
     */
    public String lowerFirstLetter(final String s) {
        if (s == null || s.length() == 0) return "";
        if (!Character.isUpperCase(s.charAt(0))) return s;
        return String.valueOf((char) (s.charAt(0) + 32)) + s.substring(1);
    }

    /**
     * Reverse the string.
     *
     * @param s The string.
     * @return the reverse string.
     */
    public String reverse(final String s) {
        if (s == null) return "";
        int len = s.length();
        if (len <= 1) return s;
        int mid = len >> 1;
        char[] chars = s.toCharArray();
        char c;
        for (int i = 0; i < mid; ++i) {
            c = chars[i];
            chars[i] = chars[len - i - 1];
            chars[len - i - 1] = c;
        }
        return new String(chars);
    }

    /**
     * Convert string to DBC.(半角)
     *
     * @param s The string.
     * @return the DBC string
     */
    public String toDBC(final String s) {
        if (s == null || s.length() == 0) return "";
        char[] chars = s.toCharArray();
        for (int i = 0, len = chars.length; i < len; i++) {
            if (chars[i] == 12288) {
                chars[i] = ' ';
            } else if (65281 <= chars[i] && chars[i] <= 65374) {
                chars[i] = (char) (chars[i] - 65248);
            } else {
                chars[i] = chars[i];
            }
        }
        return new String(chars);
    }

    /**
     * Convert string to SBC.(全角)
     *
     * @param s The string.
     * @return the SBC string
     */
    public String toSBC(final String s) {
        if (s == null || s.length() == 0) return "";
        char[] chars = s.toCharArray();
        for (int i = 0, len = chars.length; i < len; i++) {
            if (chars[i] == ' ') {
                chars[i] = (char) 12288;
            } else if (33 <= chars[i] && chars[i] <= 126) {
                chars[i] = (char) (chars[i] + 65248);
            } else {
                chars[i] = chars[i];
            }
        }
        return new String(chars);
    }

    /**
     * Convert unicode to string.
     *
     * @param unicode
     * @return
     */
    public String unicodeToString(String unicode) {
        StringBuffer string = new StringBuffer();
        String[] hex = unicode.split("\\\\u");
        for (int i = 1; i < hex.length; i++) {
            int data = Integer.parseInt(hex[i], 16);
            string.append((char) data);
        }
        return string.toString();
    }

    /**
     * Convert string to unicode.
     *
     * @param string
     * @return
     */
    public String stringToUnicode(String string) {
        StringBuffer unicode = new StringBuffer();
        for (int i = 0; i < string.length(); i++) {
            char c = string.charAt(i);
            unicode.append("\\u" + Integer.toHexString(c));
        }
        return unicode.toString();
    }

    /**
     * Convert string to hexadecimal.
     *
     * @return string
     */
    public String stringToHexString(String string) {
        String hexstring = "";
        for (int i = 0; i < string.length(); i++) {
            int ch = (int) string.charAt(i);
            String s4 = Integer.toHexString(ch);
            hexstring = hexstring + s4;
        }
        return hexstring;
    }

    /**
     * Convert hexadecimal to string.
     *
     * @return string
     */
    public String hexstringToString(String hexstring) {

        if (hexstring == null || hexstring.equals("")) {
            return null;
        }
        hexstring = hexstring.replace(" ", "");
        byte[] baKeyword = new byte[hexstring.length() / 2];
        for (int i = 0; i < baKeyword.length; i++) {
            try {
                baKeyword[i] = (byte) (0xff & Integer.parseInt(
                        hexstring.substring(i * 2, i * 2 + 2), 16));
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        try {
            hexstring = new String(baKeyword, "utf-8");
            new String();
        } catch (Exception e) {
            CaLogHelper.error(TAG, e);
        }

        return hexstring;
    }

    private static CaStringTool init;

    public static CaStringTool init() {
        if (null == init) {
            init = new CaStringTool();
        }
        return init;
    }

    //++++++++++++++++++++++++++++++++++++++
    //++ 内部方法
    //++++++++++++++++++++++++++++++++++++++

    private CaStringTool() {
        // Private constructor to prevent unwanted construction.
    }
}
